package com.hksj.crsm.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.hksj.base.entity.Properties;
import com.hksj.base.query.AlarmQuery;
import com.hksj.base.query.BaseRecordQuery;
import com.hksj.base.query.BaseSpecialityQuery;
import com.hksj.base.query.ChartQuery;
import com.hksj.base.service.DefaultAlarmService;
import com.hksj.base.service.DefaultDeviceService;
import com.hksj.base.vo.AlarmRecordVO;
import com.hksj.base.vo.DeviceVO;
import com.hksj.common.core.common.DevicePropertyConstants;
import com.hksj.common.core.exception.ApplicationException;
import com.hksj.common.core.util.EasyExcelUtil;
import com.hksj.crsm.mapper.CrsmMapper;
import com.hksj.crsm.query.CrsmDailyAlarmQuery;
import com.hksj.crsm.query.CrsmSpecialityQuery;
import com.hksj.crsm.query.SpecifiedValueRecordQuery;
import com.hksj.crsm.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CrsmService {
    @Autowired
    private DefaultDeviceService defaultDeviceService;
    @Autowired
    private DefaultAlarmService defaultAlarmService;
    @Autowired
    private CrsmMapper crsmMapper;

    public List<BarChartVO> listBarChartData(ChartQuery chartQuery) {
        SpecifiedValueRecordQuery query = new SpecifiedValueRecordQuery();
        query.setDeviceId(chartQuery.getDeviceId());
        query.setType(chartQuery.getType());
        query.setValue("1");
        query.setProperty(DevicePropertyConstants.WATER_LEAKAGE_PROPERTY_NAME);
        setQueryTime(query);
        DeviceVO deviceVO = defaultDeviceService.getDeviceInfo(chartQuery.getDeviceId());
        query.setTableName(defaultDeviceService.getTableName(deviceVO.getProductId()));
        List<BarChartVO> barChartList = crsmMapper.listWaterLeakageNum(query);
        Map<String,BarChartVO> numMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(barChartList)){
            numMap = barChartList.stream().collect(Collectors.toMap(BarChartVO::getTime, Function.identity()));
        }
        List<DateTime> rangeDayList = null;
        SimpleDateFormat dateFormat = null;

        if (query.getType() == 2){
            rangeDayList = DateUtil.rangeToList(new Date(query.getStartTime()), new Date(query.getEndTime()), DateField.DAY_OF_MONTH);
            dateFormat = new SimpleDateFormat("MM-dd");
        }

        else if (query.getType() == 3){
            rangeDayList = DateUtil.rangeToList(new Date(query.getStartTime()), new Date(query.getEndTime()), DateField.DAY_OF_MONTH);
            dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        }else if(query.getType() == 4){
            rangeDayList = DateUtil.rangeToList(new Date(query.getStartTime()), new Date(query.getEndTime()), DateField.MONTH);
            dateFormat = new SimpleDateFormat("yyyy-MM");
        } else if (query.getType() == 5){
            rangeDayList = DateUtil.rangeToList(new Date(query.getStartTime()), new Date(query.getEndTime()), DateField.MONTH);
            dateFormat = new SimpleDateFormat("yyyy-MM");
        }

        if (!ObjectUtils.isEmpty(rangeDayList)){
            List<BarChartVO> res = new ArrayList<>();
            for (DateTime dateTime : rangeDayList) {
                BarChartVO barChartVO = numMap.get(dateFormat.format(dateTime));
                if (ObjectUtils.isEmpty(barChartVO)){
                    barChartVO = new BarChartVO();
                    barChartVO.setTime(dateFormat.format(dateTime));
                }
                res.add(barChartVO);
            }
            barChartList = res;
        }
        return barChartList;
    }

    private void setQueryTime(BaseRecordQuery query){
        Date now = new Date();

        if (query.getType() == 1){
            //最近24小时 now-24h 到now
            query.setStartTime(DateUtil.offsetHour(now, -24).getTime());
            query.setEndTime(now.getTime());
        } else if (query.getType() == 2){
            //最近7天
            query.setStartTime(DateUtil.offsetDay(now, -7).getTime());
            query.setEndTime(now.getTime());
        }
        else if (query.getType() == 3){
            query.setStartTime(DateUtil.beginOfDay(DateUtil.offsetDay(now,-29)).getTime());
            query.setEndTime(now.getTime());
        }else if(query.getType() == 4){
            query.setStartTime(DateUtil.beginOfDay(DateUtil.offsetMonth(now,-11)).getTime());
            query.setEndTime(now.getTime());
        }  else if (query.getType() == 5){
            //最近半年
            query.setStartTime(DateUtil.offsetMonth(now, -6).getTime());
            query.setEndTime(now.getTime());
        }
    }

    public CrsmCurrentAlarmInfoVO getCurrentAlarmInfo(CrsmSpecialityQuery query) {
        List<PropertyAlarmNumVO> propertyAlarmNumVOList = crsmMapper.countAlarmNum(query);
        CrsmCurrentAlarmInfoVO res = new CrsmCurrentAlarmInfoVO();
        if (!ObjectUtils.isEmpty(propertyAlarmNumVOList)){
            Map<String, Integer> map = propertyAlarmNumVOList.stream().collect(Collectors.toMap(PropertyAlarmNumVO::getProperty, PropertyAlarmNumVO::getNum));
            res.setTemperatureAlarmNum(map.getOrDefault(DevicePropertyConstants.TEMPERATURE_PROPERTY_NAME,0));
            res.setWaterLeakageAlarmNum(map.getOrDefault(DevicePropertyConstants.WATER_LEAKAGE_PROPERTY_NAME,0));

            BaseSpecialityQuery baseSpecialityQuery = new BaseSpecialityQuery();
            BeanUtils.copyProperties(query,baseSpecialityQuery);
            List<AlarmRecordVO> list = defaultAlarmService.listCurrentAlarm(baseSpecialityQuery);
            res.setAlarmList(list);
        }
        return res;
    }

    public List<CrsmDailyAlarmNumVO> listDailyAlarmNum(CrsmDailyAlarmQuery query) {
        Date now = new Date();
        if (query.getDayNum() <= 0){
            throw new ApplicationException("传入的查询天数不正确");
        }
        DateTime start = DateUtil.beginOfDay(DateUtil.offsetDay(now, 1 - query.getDayNum()));
        String startTimeStr = DateUtil.formatDateTime(start);
        query.setStartTime(startTimeStr);
        query.setEndTime(DateUtil.formatDateTime(now));
        List<DailyPropertyAlarmNumVO> list = crsmMapper.listDailyAlarmNum(query);
        Map<String, Map<String, DailyPropertyAlarmNumVO>> dailyAlarmNumMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(list)){
            dailyAlarmNumMap = list.stream().collect(Collectors.groupingBy(DailyPropertyAlarmNumVO::getDay, Collectors.toMap(DailyPropertyAlarmNumVO::getProperty,Function.identity())));
        }

        List<CrsmDailyAlarmNumVO> res = new ArrayList<>();
        List<DateTime> rangeDayList = DateUtil.rangeToList(start, now, DateField.DAY_OF_MONTH);
        if (!ObjectUtils.isEmpty(rangeDayList)){
            for (DateTime dateTime : rangeDayList) {
                CrsmDailyAlarmNumVO crsmDailyAlarmNumVO = new CrsmDailyAlarmNumVO();
                crsmDailyAlarmNumVO.setDay(DateUtil.formatDate(dateTime));
                Map<String, DailyPropertyAlarmNumVO> propertyAlarmNumVOMap = dailyAlarmNumMap.get(DateUtil.formatDate(dateTime));
                if (!ObjectUtils.isEmpty(propertyAlarmNumVOMap)){
                    DailyPropertyAlarmNumVO temperature = propertyAlarmNumVOMap.get(DevicePropertyConstants.TEMPERATURE_PROPERTY_NAME);
                    if (!ObjectUtils.isEmpty(temperature)){
                        crsmDailyAlarmNumVO.setTemperatureAlarmNum(temperature.getNum());
                    }

                    DailyPropertyAlarmNumVO leakage = propertyAlarmNumVOMap.get(DevicePropertyConstants.WATER_LEAKAGE_PROPERTY_NAME);
                    if (!ObjectUtils.isEmpty(leakage)){
                        crsmDailyAlarmNumVO.setWaterLeakageAlarmNum(leakage.getNum());
                    }
                }
                res.add(crsmDailyAlarmNumVO);
            }
        }
        return res;
    }

    public void exportAlarm(AlarmQuery query, HttpServletResponse response) {
        query.setDisAblePage(true);
        List<AlarmRecordVO> records = defaultAlarmService.pageAlarmHistory(query).getRecords();
        List<CrsmAlarmExportVO> res = new ArrayList<>();
        if (!ObjectUtils.isEmpty(records)){
            for (int i = 0; i < records.size(); i++) {
                AlarmRecordVO alarmRecordVO = records.get(0);
                CrsmAlarmExportVO crsmAlarmExportVO = new CrsmAlarmExportVO();
                crsmAlarmExportVO.setSortNo(i + 1);
                crsmAlarmExportVO.setAddr(defaultDeviceService.getAddr(alarmRecordVO));
                crsmAlarmExportVO.setDeviceName(alarmRecordVO.getName());
                crsmAlarmExportVO.setRemark(alarmRecordVO.getRemark());
                crsmAlarmExportVO.setValue(alarmRecordVO.getValue());
                crsmAlarmExportVO.setCreateTime(DateUtil.formatDateTime(alarmRecordVO.getCreateTime()));
                res.add(crsmAlarmExportVO);
            }
        }

        String fileName = new StringBuffer()
                .append("机房安全监测报警")
                .append(new SimpleDateFormat("_yyyyMMddHHmmss").format(new Date()))
                .toString();
        EasyExcelUtil.exportExcelData(response,fileName,res,CrsmAlarmExportVO.class);
    }

    public void exportLeakage(BaseRecordQuery query, HttpServletResponse response) {
        query.setDisAblePage(true);
        List<Properties> records = defaultDeviceService.pageRecord(query).getRecords();
        ArrayList<CrsmExportLeakageVO> res = new ArrayList<>();
        if (!ObjectUtils.isEmpty(records)){
            for (int i = 0; i < records.size(); i++) {
                Properties properties = records.get(i);
                CrsmExportLeakageVO crsmExportLeakageVO = new CrsmExportLeakageVO();
                crsmExportLeakageVO.setSort(i + 1);
                crsmExportLeakageVO.setCreateTime(DateUtil.formatDateTime(properties.getCreateTime()));
                crsmExportLeakageVO.setLeakage(Objects.equals("1",properties.getValue()) ? "是" : "否");
                res.add(crsmExportLeakageVO);
            }
        }

        DeviceVO deviceInfo = defaultDeviceService.getDeviceInfo(query.getDeviceId());
        defaultDeviceService.wrapAddr(Arrays.asList(deviceInfo));
        String fileName = new StringBuffer()
                .append(deviceInfo.getFloorName())
                .append("_")
                .append(deviceInfo.getRoomName())
                .append("_")
                .append(deviceInfo.getName())
                .append("_")
                .append("漏水")
                .append(new SimpleDateFormat("_yyyyMMddHHmmss").format(new Date()))
                .toString();
        EasyExcelUtil.exportExcelData(response,fileName,res,CrsmExportLeakageVO.class);
    }
}
